#ifndef QRENDER_H
#define QRENDER_H

#include "glew.h"
#include "gl/glut.h"

#include <QtOpenGL/QtOpenGL>
#include <QtOpenGL/QGLWidget>

#include "QImage"
#include "QRenderIO.h"
#include "QRenderSetting.h"
#include "QRenderProgram.h"
#include "QRenderUtility.h"

#include "IO.h"
//#include "QRenderTransferFunction1DView.h"
class QRenderTransferFunction1DView;

#define FOVY            10.0
#define NEAR_CLIP       0.1
#define FAR_CLIP        100.0
#define MOUSE_SCALE     10.0
#define MAX_FRAMES      50

enum MouseMode
{
    MOUSE_ROTATE,
    MOUSE_TRANSLATE,
    MOUSE_DOLLY
};


struct DGP_Point
{
    float x;
    float y;
    float z;
    float Grayscale;
};
struct DGP_Triangle
{
    DGP_Point p1,p2,p3;
};

class QRender : public QGLWidget
{
    Q_OBJECT
    
public:
    QRender(QWidget *parent = 0);
    ~QRender();
    
    // Data file
    std::string dataFilePath, dataFileName, objectFileName, objectFileNamePrefix;

    //added by wujian 2012-06-12
    std::string *dataFileSubPathes, *dataFileNames, *objectFileNames, *objectFileNamePrefixs;
    int fileNumber;
    float *windowWidthes, *windowLevels;
    std::vector<unsigned char> *volumeDataVectors;
    float *volumeBiases, *volumeScales;
    bool shpFlag;


    // FPS
    int frames;
    double start, end;
    
    // Ray casting
    float volumeBias, volumeScale;
    float vertexScale[3], sampleScale[3];
    
    // Volume data
    float windowWidth, windowLevel;
    unsigned int bytes, steps, volumeSize[3];
    float thickness[3];
    std::vector<unsigned char> volumeData;
    float histogramData[NUMBER_HIS_ENTRIES];
    
    // Volume texture
    unsigned int type, format;
    int internalFormat;
    
    // Interaction
    float angle;
    QRenderVector3 axis;
    int mouseX, mouseY;
    MouseMode mouseMode;
    
    // Configuration
    unsigned char error;
    QRenderSetting settings;
    
    // Shading
    int currentProgram;
    std::vector<QRenderProgram> programs;

	//lxq 2011-10-3
	int currentStep;
	int totalStep;


    
    void init();
    unsigned char parseDataFile(const std::string &name);
    
    void initVolume(const std::string &name);
    unsigned char loadVolume();
    unsigned char renderTexure(int index);
    
    unsigned char initBuffers();
    unsigned char loadBuffers();
    void deleteBuffers();
    
    unsigned char initTextures();
    unsigned char initPrograms();
    unsigned char loadProgram(QRenderProgram *program, const char* name);
    void deletePrograms();
    
    void initParameters();
    void deleteParameters();
    
    void drawWireframe();
    void drawLight();
    void drawVolume();
    void saveSettings();
    void loadSettings();
    void printSettings();
    void computeFPS();


public slots:
    unsigned char updateTextures(float *transferFunction = NULL);

protected:
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void wheelEvent(QWheelEvent *event);
    void keyPressEvent(QKeyEvent *event);

private slots:
    void updateStepSize(int number);
    void updateStepBias(int number);
    void updateStepScale(int number);
    void updateDataNormalization(int state);
    void updateWireFrame(int state);

public:
    GLuint frameBufferTextures[4];
    GLuint frameBuffer;
    float visHistogram[NUMBER_HIS_ENTRIES];
    float visProbHistogram[NUMBER_HIS_ENTRIES];
    float totalVis;
    float maxVis;
    unsigned char initFrameBufferTextures();
    void calculateVisibility();
    
    QRenderTransferFunction1DView * tfView;
    void initTFView(QRenderTransferFunction1DView * view);
signals:
    void signalVolumeUpdated(float* histogramData, ::size_t histogramSize);
    void signalDestroyed();
    void signalVisUpdated(float* visHistogramData, ::size_t histogramSize);
};

#endif // QRENDER_H
